﻿using System;
using System.Drawing;
using System.Runtime.InteropServices;

namespace Pibby.Controls
{
	public static class IconReader
	{
		public static Icon GetFileIcon(string path)
		{
			return Icon.ExtractAssociatedIcon(path);
		}

		public static Icon GetFolderIcon(string path)
		{
			uint flags = SHGFI_ICON 
						//| SHGFI_USEFILEATTRIBUTES 
						| SHGFI_SMALLICON;

			var shfi = new SHFILEINFO();

			var res = NativeMethods.SHGetFileInfo(path, 
													FILE_ATTRIBUTE_DIRECTORY,
													out shfi,
													(uint)Marshal.SizeOf(shfi),
													flags);

			if (res == IntPtr.Zero)
				throw Marshal.GetExceptionForHR(Marshal.GetHRForLastWin32Error());

			var icon = (Icon)Icon.FromHandle(shfi.hIcon).Clone();

			NativeMethods.DestroyIcon(shfi.hIcon); 

			return icon;
		}

		#region Native Win32 API

		[StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto)]
		public struct SHFILEINFO
		{
			public IntPtr hIcon;
			public int iIcon;
			public uint dwAttributes;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 260)]
			public string szDisplayName;
			[MarshalAs(UnmanagedType.ByValTStr, SizeConst = 80)]
			public string szTypeName;
		};

		public const uint SHGFI_ICON = 0x000000100;
		public const uint SHGFI_USEFILEATTRIBUTES = 0x000000010;
		public const uint SHGFI_SMALLICON = 0x000000001;
		public const uint SHGFI_LARGEICON = 0x000000000;
		public const uint FILE_ATTRIBUTE_DIRECTORY = 0x00000010;

		/// <summary>
		/// WinAPI functions
		/// </summary>        
		private static class NativeMethods
		{
			[DllImport("shell32.dll", CharSet = CharSet.Auto)]
			public static extern IntPtr SHGetFileInfo(string pszPath, uint dwFileAttributes, out SHFILEINFO psfi, uint cbFileInfo, uint uFlags);

			[DllImport("user32.dll", SetLastError = true)]
			[return: MarshalAs(UnmanagedType.Bool)]
			public static extern bool DestroyIcon(IntPtr hIcon);
		}
		#endregion

	}
}
